package org.infodavid.common.impl.services.security;

import javax.persistence.PersistenceException;


import org.infodavid.common.persistence.IDataObject;
import org.infodavid.common.services.IApplicationContext;
import org.infodavid.common.services.IEntityService;
import org.infodavid.common.services.IEntityService.IInterceptorEvent;
import org.infodavid.common.services.exception.AccessDeniedException;
import org.infodavid.common.services.exceptions.ServiceException;
import org.infodavid.common.services.security.AccessControlService;
import org.infodavid.common.services.security.ISecurityInterceptor;

/**
 * The Class DefaultSecurityInterceptor.
 */
public class DefaultSecurityInterceptor<T extends IDataObject<Long>> extends InterceptorAdapter<T>
    implements ISecurityInterceptor {
	/*
	 * (non-Javadoc)
	 * @see
	 * org.infodavid.common.impl.services.security.InterceptorAdapter#preExecute(org.infodavid.common.
	 * services.IEntityService.IInterceptorEvent)
	 */
	@Override
	public void preExecute(final IInterceptorEvent event) throws PersistenceException,
	    ServiceException {
		final IApplicationContext context = event.getContext();
		final AccessControlService service = AccessControlService.getInstance();

		if (context == null) {
			throw new IllegalArgumentException("context");
		}
		else if (IEntityService.ADD_ACTION.equals(event.getAction())) {
			if (!service.isAllowed(context, context.getUser(), ISecurityInterceptor.ADD_PERMISSION)) {
				throw new AccessDeniedException("Access denied");
			}
		}
		else if (IEntityService.FIND_ACTION.equals(event.getAction())) {
			if (!service.isAllowed(context, context.getUser(), ISecurityInterceptor.READ_PERMISSION)) {
				throw new AccessDeniedException("Access denied");
			}
		}
		else if (IEntityService.GET_ACTION.equals(event.getAction())) {
			if (!service.isAllowed(context, context.getUser(), ISecurityInterceptor.READ_PERMISSION)) {
				throw new AccessDeniedException("Access denied");
			}
		}
		else if (IEntityService.REMOVE_ACTION.equals(event.getAction())) {
			if (!service.isAllowed(context, context.getUser(), ISecurityInterceptor.DELETE_PERMISSION)) {
				throw new AccessDeniedException("Access denied");
			}
		}
		else if (IEntityService.UPDATE_ACTION.equals(event.getAction())) {
			if (!service.isAllowed(context, context.getUser(), ISecurityInterceptor.WRITE_PERMISSION)) {
				throw new AccessDeniedException("Access denied");
			}
		}
		else {
			if (!service.isAllowed(context, context.getUser(), ISecurityInterceptor.READ_PERMISSION)) {
				throw new AccessDeniedException("Access denied");
			}
		}
	}

	/*
	 * See super class or interface. (non-Javadoc)
	 * @see org.infodavid.common.services.security.ISecurityInterceptor#getAvailablePermissions()
	 */
	public String[] getAvailablePermissions() {
		return BASIC_PERMISSIONS;
	}
}
